package com.ecoolex.ying.space.core.manager;

import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.util.*;
import com.ecoolex.ying.space.core.CoreConstant;
import com.ecoolex.ying.space.core.dao.DesignerProjectShareDAO;
import com.ecoolex.ying.space.entity.DesignerProjectShare;
import com.ecoolex.ying.space.entity.DesignerProjectShare.Column;
import com.ecoolex.ying.space.entity.DesignerProjectShareExample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.TimeZone;

import static com.ecoolex.ying.space.entity.DesignerProjectShare.IS_DELETED;
import static com.ecoolex.ying.space.entity.DesignerProjectShare.NOT_DELETED;

@Service
public class DesignerProjectShareManager {
    @Autowired
    private DesignerProjectShareDAO dao;

    public DesignerProjectShare reset(Integer userId, Integer projectId, Integer expirydateDay, String updateUser) {
        BizAssert.isTrue(Check.notNullAndGteZero(expirydateDay) && expirydateDay <= 30, ResultCode.VERIFY.build(10), "有效期天数不能为null并且必须在0-30范围内");

        // 访问密码
        String password = RandomUtil.randomInt(4);
        String number = String.format("%d1%011d%s", LocalTime.now().getSecond(), projectId, password);
        // 计算有效期
        Date expirydate = expirydateDay == 0 ?
                Date.from(CoreConstant.DESIGNER_PROJECT_SHARE_MAX_EXPIRYDATE.toInstant(ZoneOffset.UTC))
                : Date.from(Instant.now().plus(expirydateDay, ChronoUnit.DAYS));

        DesignerProjectShare record = new DesignerProjectShare();
        record.setProjectId(projectId);
        record.setUserId(userId);
        record.setShareId(TinyId.encode(Long.valueOf(number)));
        record.setSharePassword(password);
        record.setExpirydateDay(expirydateDay);
        record.setExpirydate(expirydate);
        record.setDeleted(NOT_DELETED);
        record.setCreateUser(updateUser);
        record.setCreateTime(Date.from(Instant.now()));
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));

        if (!update(record)) {
            create(record);
        }
        return record;
    }

    private boolean update(DesignerProjectShare record) {
        DesignerProjectShareExample example =new DesignerProjectShareExample();
        example.createCriteria()
                .andProjectIdEqualTo(record.getProjectId())
                .andDeletedEqualTo(NOT_DELETED);

        int row = dao.updateByExampleSelective(record, example, Column.excludes(Column.createUser,
                Column.createTime));
        return row == 1;
    }

    private void create(DesignerProjectShare record) {
        dao.insert(record);
    }

    public void clear(Integer userId, Integer projectId) {
        DesignerProjectShareExample example = new DesignerProjectShareExample();
        example.createCriteria()
                .andUserIdEqualTo(userId)
                .andProjectIdEqualTo(projectId)
                .andDeletedEqualTo(NOT_DELETED);
        dao.deleteByExample(example);
    }

    void deleteByProjectId(Integer projectId, String updateUser) {
        DesignerProjectShare record = new DesignerProjectShare();
        record.setDeleted(IS_DELETED);
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));

        DesignerProjectShareExample example = new DesignerProjectShareExample();
        example.createCriteria()
                .andProjectIdEqualTo(projectId)
                .andDeletedEqualTo(NOT_DELETED);

        dao.updateByExampleSelective(record,
                example,
                Column.deleted,
                Column.updateUser,
                Column.updateTime);
    }

    public DesignerProjectShare getByProjectId(Integer projectId) {
        return dao.selectByPrimaryKeyWithLogicalDelete(projectId, NOT_DELETED);
    }

    public DesignerProjectShare getByShareId(String shareId) {
        DesignerProjectShareExample example = new DesignerProjectShareExample();
        example.createCriteria()
                .andShareIdEqualTo(shareId)
                .andDeletedEqualTo(NOT_DELETED);

        return dao.selectOneByExample(example);
    }

    public DesignerProjectShare getByShareIdAndPassword(String shareId, String password) {
        DesignerProjectShareExample example = new DesignerProjectShareExample();
        example.createCriteria()
                .andShareIdEqualTo(shareId)
                .andSharePasswordEqualTo(password)
        .andDeletedEqualTo(NOT_DELETED);

        return dao.selectOneByExample(example);
    }

}